package com.zxy.config.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author: Zxy
 * @description: 自定义异步线程池，处理文件上传以及短信验证码
 * @date: 2021-07-09 09:25
 */
@Slf4j
@Configuration
public class NativeAsyncTaskPool implements AsyncConfigurer {

    @Autowired
    @Qualifier("asyncThreadPoolParam")
    private AsyncThreadPoolParam poolParam;

    @Override
    public Executor getAsyncExecutor() {
        // 这个类对ThreadPoolExecutor进行了一次封装，使用的队列是阻塞队列和链表队列
        /*
        private final Object poolSizeMonitor = new Object(); // 池线程大小监视器锁
        private int corePoolSize = 1; // 核心线程数
        private int maxPoolSize = 2147483647; // 最大线程数
        private int keepAliveSeconds = 60; // 存活时间 秒
        private int queueCapacity = 2147483647; // 队列容量 如果给定的初始容量大于0，那么使用链表阻塞队列，否则使用非公平的锁队列
        private boolean allowCoreThreadTimeOut = false; // 是否允许核心线程超时处理
        @Nullable
        private TaskDecorator taskDecorator;
        @Nullable
        private ThreadPoolExecutor threadPoolExecutor;
        private final Map<Runnable, Object> decoratedTaskMap;
        * */
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(poolParam.getCorePoolSize());
        executor.setMaxPoolSize(poolParam.getMaxPoolSize());
        executor.setKeepAliveSeconds(poolParam.getKeepAliveSeconds());
        executor.setQueueCapacity(poolParam.getQueueCapacity());
        // 这个拒绝策略可以实现当队列满了之后实现自定义伸缩
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化这个线程池
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}
